package io.github.talelin.latticy.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.github.talelin.autoconfigure.exception.ForbiddenException;
import io.github.talelin.latticy.common.mybatis.Page;
import io.github.talelin.latticy.dto.rule.ruleKey.RuleFieldDTO;
import io.github.talelin.latticy.dto.rule.ruleKey.RuleKeyDTO;
import io.github.talelin.latticy.model.RuleKeyDO;
import io.github.talelin.latticy.mapper.RuleKeyMapper;
import io.github.talelin.latticy.service.RuleKeyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author generator@wulongbo
 * @since 2022-08-23
 */
@Service
public class RuleKeyServiceImpl extends ServiceImpl<RuleKeyMapper, RuleKeyDO> implements RuleKeyService {

    @Override
    public boolean addRuleKey(RuleKeyDTO dto) {
        checkRuleKeyExistByKeyAndValue(dto);
        return this.save(new RuleKeyDO(dto));
    }

    @Override
    public boolean updateRuleKeyById(RuleKeyDTO dto, Integer id) {
        checkRuleKeyExistByKeyAndValue(dto, id);
        return this.updateById(new RuleKeyDO(dto, id));
    }

    @Override
    public boolean deleteRuleKeyById(Integer id) {
        return this.baseMapper.deleteById(id) > 0;
    }

    @Override
    public RuleKeyDO getRuleKeyById(Integer id) {
        return this.getById(id);
    }

    @Override
    public List<RuleKeyDO> getRuleKeyList(RuleFieldDTO dto) {
        QueryWrapper<RuleKeyDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(RuleKeyDO::getFeesBizType, dto.getFeesBizType()).eq(RuleKeyDO::getLevel, dto.getLevel())
                .eq(RuleKeyDO::getType, dto.getType());
        return this.list(wrapper);
    }

    @Override
    public IPage<RuleKeyDO> getRuleKeyPage(Integer page, Integer count, Integer feesBizType, Integer level, Integer type, Integer frameType) {
        Page<RuleKeyDO> pager = new Page<>(page, count);
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<RuleKeyDO>().eq(feesBizType != null, RuleKeyDO::getFeesBizType, feesBizType)
                .eq(level != null, RuleKeyDO::getLevel, level).eq(type != null, RuleKeyDO::getType, type)
                .eq(frameType != null, RuleKeyDO::getFrameType, frameType);
        return this.baseMapper.selectPage(pager, wrapper);
    }

    private void checkRuleKeyExistByKeyAndValue(RuleKeyDTO dto) {
        LambdaQueryWrapper<RuleKeyDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RuleKeyDO::getFeesBizType, dto.getFeesBizType());
        wrapper.eq(RuleKeyDO::getLevel, dto.getLevel());
        wrapper.eq(RuleKeyDO::getType, dto.getType());
        wrapper.and(x -> x.eq(RuleKeyDO::getFtlKey, dto.getFtlKey()).or().eq(RuleKeyDO::getFtlValue, dto.getFtlValue()));
        int count = this.count(wrapper);
        if (count > 0) {
            throw new ForbiddenException(18801);
        }
    }

    private void checkRuleKeyExistByKeyAndValue(RuleKeyDTO dto, Integer id) {
        LambdaQueryWrapper<RuleKeyDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RuleKeyDO::getFeesBizType, dto.getFeesBizType());
        wrapper.eq(RuleKeyDO::getLevel, dto.getLevel());
        wrapper.ne(RuleKeyDO::getId, id);
        wrapper.and(x -> x.eq(RuleKeyDO::getFtlKey, dto.getFtlKey()).or().eq(RuleKeyDO::getFtlValue, dto.getFtlValue()));
        int count = this.count(wrapper);
        if (count > 0) {
            throw new ForbiddenException(18801);
        }
    }
}
